home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / Exploit and vulnerability / w00w00 / sectools / fragrouter / libpcap-0.4 / pcap-enet.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-07-26  |  4.7 KB  |  228 lines

  1. /*
  2.  * Stanford Enetfilter subroutines for tcpdump
  3.  *
  4.  * Based on the MERIT NNstat etherifrt.c and the Ultrix pcap-pf.c
  5.  * subroutines.
  6.  *
  7.  * Rayan Zachariassen, CA*Net
  8.  */
  9.  
  10. #include <sys/types.h>
  11. #include <sys/time.h>
  12. #include <sys/file.h>
  13. #include <sys/ioctl.h>
  14. #include <sys/socket.h>
  15.  
  16. #include <net/if.h>
  17. #include <net/bpf.h>
  18. #include <net/enet.h>
  19.  
  20. #include <netinet/in.h>
  21. #include <netinet/if_ether.h>
  22.  
  23. #include <stdio.h>
  24. #include <errno.h>
  25.  
  26. #include "interface.h"
  27.  
  28. struct packet_header {
  29. #ifdef    IBMRTPC
  30.     struct LengthWords    length;
  31.     struct tap_header    tap;
  32. #endif    /* IBMRTPC */
  33.     u_char            packet[8]
  34. };
  35.  
  36. extern int errno;
  37.  
  38. #define BUFSPACE (4*1024)
  39.  
  40. /* Forwards */
  41. static void efReadError(int, char *);
  42.  
  43. void
  44. readloop(int cnt, int if_fd, struct bpf_program *fp, printfunc printit)
  45. {
  46. #ifdef    IBMRTPC
  47.     register struct packet_header *ph;
  48.     register u_char *bp;
  49.     register int inc;
  50. #else    /* !IBMRTPC */
  51.     static struct timeval tv = { 0 };
  52. #endif    /* IBMRTPC */
  53.     register int cc, caplen;
  54.     register struct bpf_insn *fcode = fp->bf_insns;
  55.     union {
  56.         struct packet_header hdr;
  57.         u_char    p[BUFSPACE];
  58.         u_short    s;
  59.     } buf;
  60.  
  61.     while (1) {
  62.         if ((cc = read(if_fd, (char *)buf.p, sizeof(buf))) < 0)
  63.             efReadError(if_fd, "reader");
  64.  
  65. #ifdef    IBMRTPC
  66.         /*
  67.          * Loop through each packet.
  68.          */
  69.         bp = buf.p;
  70.         while (cc > 0) {
  71.             ph = (struct packet_header *)bp;
  72.             caplen = ph->tap.th_wirelen > snaplen ? snaplen : ph->tap
  73. .th_wirelen ;
  74.             if (bpf_filter(fcode, (char *)ph->packet,
  75.                         ph->tap.th_wirelen, caplen)) {
  76.                 if (cnt >= 0 && --cnt < 0)
  77.                     goto out;
  78.                 (*printit)((char *)ph->packet,
  79.                     (struct timeval *)ph->tap.th_timestamp,
  80.                     ph->tap.th_wirelen, caplen);
  81.             }
  82.             inc = ph->length.PacketOffset;
  83.             cc -= inc;
  84.             bp += inc;
  85.         }
  86. #else    /* !IBMRTPC */
  87.         caplen = cc > snaplen ? snaplen : cc ;
  88.         if (bpf_filter(fcode, buf.hdr.packet, cc, caplen)) {
  89.             if (cnt >= 0 && --cnt < 0)
  90.                 goto out;
  91.             (*printit)(buf.hdr.packet, &tv, cc, caplen);
  92.         }
  93. #endif    /* IBMRTPC */
  94.     }
  95.  out:
  96.     wrapup(if_fd);
  97. }
  98.  
  99. /* Call ONLY if read() has returned an error on packet filter */
  100. static void
  101. efReadError(int fid, char *msg)
  102. {
  103.     if (errno == EINVAL) {    /* read MAXINT bytes already! */
  104.         if (lseek(fid, 0, 0) < 0) {
  105.             perror("tcpdump: efReadError/lseek");
  106.             exit(-1);
  107.         }
  108.         else
  109.             return;
  110.     }
  111.     else {
  112.         (void) fprintf(stderr, "tcpdump: ");
  113.         perror(msg);
  114.         exit(-1);
  115.     }
  116. }
  117.  
  118. void
  119. wrapup(int fd)
  120. {
  121. #ifdef    IBMRTPC
  122.     struct enstats es;
  123.  
  124.     if (ioctl(fd, EIOSTATS, &es) == -1) {
  125.         perror("tcpdump: enet ioctl EIOSTATS error");
  126.         exit(-1);
  127.     }
  128.     
  129.     fprintf(stderr, "%d packets queued", es.enStat_Rcnt);
  130.     if (es.enStat_Rdrops > 0)
  131.         fprintf(stderr, ", %d dropped", es.enStat_Rdrops);
  132.     if (es.enStat_Reads > 0)
  133.         fprintf(stderr, ", %d tcpdump %s", es.enStat_Reads,
  134.                 es.enStat_Reads > 1 ? "reads" : "read");
  135.     if (es.enStat_MaxRead > 1)
  136.         fprintf(stderr, ", %d packets in largest read", 
  137.             es.enStat_MaxRead);
  138.     putc('\n', stderr);
  139. #endif    /* IBMRTPC */
  140.     close(fd);
  141. }
  142.  
  143. int
  144. initdevice(char *device, int pflag, int *linktype)
  145. {
  146.     struct eniocb ctl;
  147.     struct enfilter filter;
  148.     u_int maxwaiting;
  149.     int if_fd;
  150.  
  151. #ifdef    IBMRTPC
  152.     GETENETDEVICE(0, O_RDONLY, &if_fd);
  153. #else    /* !IBMRTPC */
  154.     if_fd = open("/dev/enet", O_RDONLY, 0);
  155. #endif    /* IBMRTPC */
  156.  
  157.     if (if_fd == -1) {
  158.         perror("tcpdump: enet open error");
  159.         error(
  160. "your system may not be properly configured; see \"man enet(4)\"");
  161.         exit(-1);
  162.     }
  163.  
  164.     /*  Get operating parameters. */
  165.  
  166.     if (ioctl(if_fd, EIOCGETP, (char *)&ctl) == -1) {
  167.         perror("tcpdump: enet ioctl EIOCGETP error");
  168.         exit(-1);
  169.     }
  170.  
  171.     /*  Set operating parameters. */
  172.  
  173. #ifdef    IBMRTPC
  174.     ctl.en_rtout = 1 * ctl.en_hz;
  175.     ctl.en_tr_etherhead = 1;
  176.     ctl.en_tap_network = 1;
  177.     ctl.en_multi_packet = 1;
  178.     ctl.en_maxlen = BUFSPACE;
  179. #else    /* !IBMRTPC */
  180.     ctl.en_rtout = 64;    /* randomly picked value for HZ */
  181. #endif    /* IBMRTPC */
  182.     if (ioctl(if_fd, EIOCSETP, &ctl) == -1) {
  183.         perror("tcpdump: enet ioctl EIOCSETP error");
  184.         exit(-1);
  185.     }
  186.  
  187.     /*  Flush the receive queue, since we've changed
  188.         the operating parameters and we otherwise might
  189.         receive data without headers. */
  190.  
  191.     if (ioctl(if_fd, EIOCFLUSH) == -1) {
  192.         perror("tcpdump: enet ioctl EIOCFLUSH error");
  193.         exit(-1);
  194.     }
  195.  
  196.     /*  Set the receive queue depth to its maximum. */
  197.  
  198.     maxwaiting = ctl.en_maxwaiting;
  199.     if (ioctl(if_fd, EIOCSETW, &maxwaiting) == -1) {
  200.         perror("tcpdump: enet ioctl EIOCSETW error");
  201.         exit(-1);
  202.     }
  203.  
  204. #ifdef    IBMRTPC
  205.     /*  Clear statistics. */
  206.  
  207.     if (ioctl(if_fd, EIOCLRSTAT, 0) == -1) {
  208.         perror("tcpdump: enet ioctl EIOCLRSTAT error");
  209.         exit(-1);
  210.     }
  211. #endif    /* IBMRTPC */
  212.  
  213.     /*  Set the filter (accept all packets). */
  214.  
  215.     filter.enf_Priority = 3;
  216.     filter.enf_FilterLen = 0;
  217.     if (ioctl(if_fd, EIOCSETF, &filter) == -1) {
  218.         perror("tcpdump: enet ioctl EIOCSETF error");
  219.         exit(-1);
  220.     }
  221.     /*
  222.      * "enetfilter" supports only ethernets.
  223.      */
  224.     *linktype = DLT_EN10MB;
  225.  
  226.     return(if_fd);
  227. }
  228.